package com.shelpe.services.simbasync.service.impl;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.shelpe.services.simbasync.dao.InsightKeywordDataMapper;
import com.shelpe.services.simbasync.dao.KeywordsMapper;
import com.shelpe.services.simbasync.dao.RptKeywordMapper;
import com.shelpe.services.simbasync.dto.InsightWordData;
import com.shelpe.services.simbasync.exception.ApiException;
import com.shelpe.services.simbasync.model.InsightKeywordData;
import com.shelpe.services.simbasync.model.Keywords;
import com.shelpe.services.simbasync.model.KeywordsExample;
import com.shelpe.services.simbasync.model.RptKeyword;
import com.shelpe.services.simbasync.model.RptKeywordExample;
import com.shelpe.services.simbasync.model.mongo.KeywordStrTemp;
import com.shelpe.services.simbasync.model.mongo.Scope;
import com.shelpe.services.simbasync.model.mongo.WordInsightMetric;
import com.shelpe.services.simbasync.mongorepository.KeywordMetricRepository;
import com.shelpe.services.simbasync.mongorepository.KeywordStrTempRepository;
import com.shelpe.services.simbasync.service.KeywordsService;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy.InsightKeywordDataResponse;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy.InsightWord;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy.InsightWordDataResponse;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy.QscoreResponse;
import com.shelpe.services.simbasync.service.simbaproxy.KeywordsProxy.Score;
import com.shelpe.services.simbasync.util.Util;


/**
 * 实现以下两部分功能
 * 
 * 1、从代理服务器获取数据（只负责读取）
 * 
 * 2、对本地数据的增、删、查、改
 * 
 * */
@Service
public class KeywordsServiceImpl implements KeywordsService {
	

	private static final Logger logger = LoggerFactory.getLogger(KeywordsServiceImpl.class);
	
	@Autowired
	private KeywordsMapper mapper;
	
	@Autowired
	private RptKeywordMapper rptmapper;
	
	@Autowired 
	private InsightKeywordDataMapper insightKeywordMapper;
	
	@Autowired
	private KeywordsProxy proxy;
	
	@Autowired
	private KeywordMetricRepository keywordRep;
	
	@Autowired
	private KeywordStrTempRepository wordTempRep;
	
	@Override
	public int addKeywords(String userId, Keywords keywords) {
		keywords.setUser_id(userId);
		return mapper.insert(keywords);
	}
	
	@Override
	public int addKeywordsList(String userId, List<Keywords> keywords) {

		int num = 0;
		for(Keywords item : keywords){
			item.setUser_id(userId);
			num += mapper.insert(item);
		}
		return num;
	}
	
	@Override
	public int insertKeywordsBatch(String userId, List<Keywords> list){
		
		if(list == null || list.size() == 0){
			return 0;
		}
		
		return mapper.insertBatch(userId, list);
	}
	
	@Override
	public int setKeywordsPrice(String userId, List<Keywords> keywords) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Keywords item : keywords){
			item.setUser_id(userId);
			num += mapper.updateByPrimaryKey(item);
		}
		
		return num;
	}
	
	@Override
	public List<String> getWordByUserId(String userId){
		
		return mapper.selectWordByUserId(userId);
	}
	
	@Override
	public List<Keywords> parseJsonToKeywords(String response){

		List<Keywords> list = new ArrayList<Keywords>();
		
		if(response != null && response.contains("simba_keywordsbyadgroupid_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_keywordsbyadgroupid_get_response");
			JSONObject objItems = objRes==null? null : objRes.getJSONObject("keywords");
			JSONArray jsonList = objItems==null? null : objItems.getJSONArray("keyword");
			int size = jsonList == null? 0 : jsonList.size();
		
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				//解析
				Keywords keyword = new Keywords();
				
				int matchscope = 0;
				int qscore = 0;
				
				matchscope = NumberUtils.toInt(item.getString("match_scope"), 0);
				qscore = NumberUtils.toInt(item.getString("qscore"), 0);
				
				keyword.setAdgroupId(item.getLong("adgroup_id"));
				keyword.setCampaignId(item.getLong("campaign_id"));
				keyword.setCreateTime(item.getDate("create_time"));
				keyword.setModifiedTime(item.getDate("modified_time"));
				keyword.setNick(item.getString("nick"));
				String auditDesc = item.getString("audit_desc");
				auditDesc = auditDesc == null ? "" : auditDesc;
				keyword.setAuditDesc(auditDesc);
				keyword.setAuditStatus(item.getString("audit_status"));
				keyword.setIsDefaultPrice(item.getBoolean("is_default_price"));
				keyword.setIsGarbage(item.getBoolean("is_garbage"));
				keyword.setKeywordId(item.getLong("keyword_id"));
				//match_scope
				keyword.setMatchscope(matchscope);
				keyword.setMaxMobilePrice(item.getInteger("max_mobile_price"));
				keyword.setMaxPrice(item.getInteger("max_price"));
				keyword.setMobileIsDefaultPrice(item.getInteger("mobile_is_default_price"));
				keyword.setQscore(qscore);
				keyword.setWord(item.getString("word"));
				
				list.add(keyword);
			}	
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is parseJsonToKeywords, response: {}", response);
			throw new ApiException();
		}
		
		return list;
	}
	
	@Override
	public void updateKeywordsData(String userId, List<Keywords> list){
		
		Date updatedTime = new Date();
		
		for(Keywords keyword : list){
			keyword.setUser_id(userId);
			keyword.setUpdatedTime(updatedTime);
			keyword.setOrder((short)0);
			keyword.setRankScore((short)0);
			keyword.setSmartPrice(false);
			keyword.setWirelessQscore(0);
		}
	}

	@Override
	public int addRptKeywords(String userId, RptKeyword rpt) {
		// TODO Auto-generated method stub
		rpt.setUser_id(userId);
		return rptmapper.insert(rpt);
	}

	@Override
	public int addRptKeywordsList(String userId, List<RptKeyword> rptList) {
		// TODO Auto-generated method stub
		int num = 0;
		for(RptKeyword item : rptList){
			item.setUser_id(userId);
			num += rptmapper.insert(item);
		}
		return num;
	}
	
	@Override
	public int deleteRptKeywordsByDateRange(String userId, List<Long> adgroupIds, Date startDate, Date endDate){
		
		RptKeywordExample example = new RptKeywordExample();
		example.createCriteria()
		.andDateBetween(startDate, endDate)
		.andAdgroupIdIn(adgroupIds);
		
		return rptmapper.deleteByExample(userId, example);
	}
	
	@Override
	public int insertRptKeywordsBatch(String userId, List<RptKeyword> rptList){
		int num = 0;
		int pageSize = 15000;
		if(rptList != null && rptList.size() > 0){
			int fromIndex = 0;
			int endIndex = 0;
			do{
				endIndex += pageSize; 
				if(endIndex > rptList.size()){
					endIndex = rptList.size();
				}
				num += rptmapper.insertBatch(userId,rptList.subList(fromIndex, endIndex));	
				fromIndex += pageSize; 
			
			}while(fromIndex < rptList.size());
			
		}
		
		return num;
	}
	
	public int deleteRptKeywordByUserIdDate(String userId, Date date){
		RptKeywordExample example = new  RptKeywordExample();
		example.createCriteria().andDateEqualTo(date)
				.andSourceNotEqualTo(Byte.valueOf("23"));
		return rptmapper.deleteByExample(userId, example);
	}
	
	@Override
	public List<Keywords> getKeywordsByUserId(String userId){
		
		KeywordsExample ex = new KeywordsExample();
		
		return mapper.selectByExample(userId, ex);
	}
	
	@Override
	public List<Keywords> getKeywordsByAdGroupId(String userId, Long adgroupId) {
		// TODO Auto-generated method stub
		KeywordsExample ex = new KeywordsExample();
		ex.createCriteria().andAdgroupIdEqualTo(adgroupId);
		
		return mapper.selectByExample(userId, ex);
	}
	
	@Override
	public List<Keywords> getKeywordsByWirelessQscore(String userId, Long adgroupId){
		
		KeywordsExample ex = new KeywordsExample();
		
		ex.createCriteria()
			.andAdgroupIdEqualTo(adgroupId)
			.andWirelessQscoreEqualTo(0);
		
		return mapper.selectByExample(userId, ex);
	}
	
	@Override
	public List<Keywords> getKeywordIdsScore(String nick, Long adgroupId, List<Keywords> keywords, List<Score> scoreList){
		
		int pageSize = 20;
		int fromIndex = 0;
		int endIndex = 0;
		Map<Long, Integer> idScore = new HashMap<Long, Integer>();
	
		do{
			endIndex += pageSize; 
			if(endIndex > keywords.size()){
				endIndex = keywords.size();
			}
			
			StringBuilder sb = new StringBuilder();
			int index = fromIndex;
			for(; index < endIndex-1; index++){
				sb.append(keywords.get(index).getKeywordId());
				sb.append(",");
			}
			sb.append(keywords.get(index).getKeywordId());
			
			boolean hasError = true;
			int retry = 0;
			
			do{	
				QscoreResponse res = null;
				res = proxy.getKeywordsNewScore(nick, adgroupId, sb.toString());
				
				if(res != null && res.getRes() != null && res.getRes().getResult1() != null
						&& res.getRes().getResult1().getResult() != null 
						&& res.getRes().getResult1().getResult().getListRes() != null){
					
					List<Score> score = res.getRes().getResult1().getResult().getListRes().getList();
					if(score != null && score.size() > 0){
						Score scoreTest = score.iterator().next();
						if(scoreTest.getWord() != null || scoreTest.getQscore() != null || scoreTest.getWirelessQscore() != null){//异常情况下，忽略
							scoreList.addAll(score);
							for(Score item : score){
								idScore.put(item.getKeywordId(), NumberUtils.toInt(item.getWirelessQscore(), 0));
							}
							hasError = false;
						}
					}
				}		
				retry++;
				if(retry >= 3){
					logger.warn("getKeywordIdsScore, something may be wrong, adgroupId {}", adgroupId);
				}
				
			}while(hasError && retry < 3);
	
			fromIndex += pageSize; 
			
		}while(fromIndex < keywords.size());	
		
		List<Keywords> result = new ArrayList<Keywords>();
		
		for(Keywords keyword : keywords){
			Integer singleScore = idScore.get(keyword.getKeywordId());
			if(singleScore != null && (!singleScore.equals(keyword.getWirelessQscore()))){
				
				keyword.setWirelessQscore(singleScore);
				result.add(keyword);
			}
		}
		
		return result;
	}
	
	@Override
	public int deleteKeywords(String userId, Keywords ad) {
		// TODO Auto-generated method stub
		return mapper.deleteByPrimaryKey(userId, ad.getKeywordId());
	}

	@Override
	public int deleteKeywordsList(String userId, List<Keywords> adList) {
		// TODO Auto-generated method stub
		int num = 0;
		for(Keywords key : adList){
			num += deleteKeywords(userId, key);
		}
		return num;
	}

	@Override
	public int updateKeywords(String userId, Keywords ad) {
		// TODO Auto-generated method stub
		ad.setUser_id(userId);
		return mapper.updateByPrimaryKey(ad);
	}

	@Override
	public int updateKeywordsList(String userId, List<Keywords> adList) {
		// TODO Auto-generated method stub
		int num = 0;

		if(adList != null && adList.size() > 0){
			
			for(Keywords key : adList){
				key.setUser_id(userId);
				num += mapper.updateByPrimaryKey(key);
			}
		}
		
		return num;
	}

	@Override
	public Map<String, List<Keywords>> splitKeywords(List<Keywords> newList, List<Keywords> oldList) {
		// TODO Auto-generated method stub
		Map<String, List<Keywords> > ret = new HashMap<String, List<Keywords> >();
		List<Keywords> updated = new ArrayList<Keywords>();
		List<Keywords> deleted = new ArrayList<Keywords>();
		List<Keywords> added = new ArrayList<Keywords>();
		Set<Long> newAdIds = new HashSet<Long>();
		int oldSize = oldList == null? 0 : oldList.size();
		int i = 0;
		
		for(Keywords newItem : newList){
			
			for(i = 0; i < oldSize; i++){
				Keywords oldItem = oldList.get(i);
				if(newItem.getKeywordId().equals(oldItem.getKeywordId())){
					//比较其他字段是否相同
					if(!isEqualKeywords(newItem, oldItem)){
						if(oldItem.getOrder() != null){
							newItem.setOrder(oldItem.getOrder());
						}
						if(oldItem.getRankScore() != null){
							newItem.setRankScore(oldItem.getRankScore());
						}
						if(oldItem.getSmartPrice() != null){
							newItem.setSmartPrice(oldItem.getSmartPrice());
						}
						if(oldItem.getWirelessQscore() != null){
							newItem.setWirelessQscore(oldItem.getWirelessQscore());
						}
						
						updated.add(newItem);
					}
					break;
				}
			}
			
			if(i == oldSize){
				added.add(newItem);
			}
			newAdIds.add(newItem.getKeywordId());
		}
		
		for(Keywords oldItem : oldList){
			if(!newAdIds.contains(oldItem.getKeywordId())){
				deleted.add(oldItem);
			}
		}
		ret.put("delete", deleted);	
		ret.put("update", updated);	
		ret.put("add", added);	
				
		return ret;
	}
	
	private boolean isEqualKeywords(Keywords newAd, Keywords oldAd){
		
		if(newAd.getAuditDesc().equals(oldAd.getAuditDesc()) &&
				newAd.getQscore().equals(oldAd.getQscore()) &&
				newAd.getMaxPrice().equals(oldAd.getMaxPrice()) &&
				newAd.getMaxMobilePrice().equals(oldAd.getMaxMobilePrice()) &&
				newAd.getModifiedTime().getTime() == oldAd.getModifiedTime().getTime() &&
				newAd.getAuditStatus().equals(oldAd.getAuditStatus()) &&
				newAd.getIsGarbage().equals(oldAd.getIsGarbage())){
			return true;
		}
		
		return false;
	}

	@Override
	public Date getLastTimeFromRpt(String userId, long campaignId, long adgroupId) {
		// TODO Auto-generated method stub
		return rptmapper.getLastTimeFromRpt(userId, campaignId, adgroupId);
	}
	
	@Override
	public Date getLastTimeFromRptScore(String userId, long adgroupId){
		
		return rptmapper.getLastTimeFromRptScore(userId, adgroupId);
	}

	@Override
	public List<RptKeyword> parseJsonToRptKeywordBase(String response) {
		// TODO Auto-generated method stub

		List<RptKeyword> ret = new ArrayList<RptKeyword>();
		
		if(response != null && response.contains("simba_rpt_adgroupkeywordbase_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_rpt_adgroupkeywordbase_get_response");
			JSONArray jsonList = null;
			try{
				
				jsonList = objRes==null? null : objRes.getJSONArray("rpt_adgroupkeyword_base_list");
			}catch(Exception e){
				logger.warn("parseJsonToRptKeywordBase error objRes {}", objRes.toJSONString());
				throw e;
			}
			
			int size = jsonList == null? 0 : jsonList.size();
			
			Map<String, Byte> map = new HashMap<String, Byte>();
			map.put("SEARCH", Byte.valueOf("0"));
			map.put("CAT", Byte.valueOf("1"));
			map.put("NOSEARCH", Byte.valueOf("2"));
			map.put("SUMMARY", Byte.valueOf("3"));
			
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				RptKeyword rpt = new RptKeyword();

				int impression = NumberUtils.toInt(item.getString("impressions"), 0);
				int cost = NumberUtils.toInt(item.getString("cost"), 0);
				int click = NumberUtils.toInt(item.getString("click"), 0);
				float ctr = NumberUtils.toFloat(item.getString("ctr"), 0.0f);
				float cpc = NumberUtils.toFloat(item.getString("cpc"), 0.0f);
				float cpm = NumberUtils.toFloat(item.getString("cpm"), 0.0f);
				float avgpos = NumberUtils.toFloat(item.getString("avgpos"), 0.0f);
				
				rpt.setCpc(cpc);
				rpt.setCtr(ctr) ;
				rpt.setImpressions(impression) ;
				rpt.setCpm(cpm);
				rpt.setClick(click);
				rpt.setCost(cost) ;
				rpt.setAdgroupId(item.getLong("adgroupid"));
				rpt.setCampaignId(item.getLong("campaignid"));
				rpt.setDate(item.getDate("date"));
				
				rpt.setSearchType(map.get(item.getString("searchtype")));
				
				rpt.setSource(item.getByte("source"));
				rpt.setAvgpos(avgpos);
				rpt.setKeywordId(item.getLong("keywordid"));
				rpt.setKeywordstr(item.getString("keywordstr"));
				
				rpt.setDirectPay(0);
				rpt.setIndirectPay(0); 
				rpt.setDirectPayCount(0);
				rpt.setIndirectPayCount(0);
				rpt.setFavShopCount(0);
				rpt.setFavItemCount(0); 	
				rpt.setCartTotal(0);
				rpt.setDirectCartTotal(0);
				rpt.setIndirectCartTotal(0);
				rpt.setQscore(0);
				rpt.setWirelessQscore(0);
				
				ret.add(rpt);
			}
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is parseJsonToRptKeywordBase, response: {}", response);
			throw new ApiException();
		}
		
		return ret;
	}

	@Override
	public int combineRptKeywordEffect(String response, Map<String, Integer> lastDayRecord, List<RptKeyword> list) {
		// TODO Auto-generated method stub
		int size = 0;
		int lastDayRecordTotal = 0;
		int lastDayNoDataNum = 0;
		if(response != null && response.contains("simba_rpt_adgroupkeywordeffect_get_response")){
			JSONObject object = JSON.parseObject(response);
			JSONObject objRes = object==null? null : object.getJSONObject("simba_rpt_adgroupkeywordeffect_get_response");
			JSONArray jsonList = objRes==null? null : objRes.getJSONArray("rpt_adgroupkeyword_effect_list");
			size = jsonList == null? 0 : jsonList.size();
			Date lastDay = Util.getLastDayYYYYMMDD();
			
			Map<String, Byte> map = new HashMap<String, Byte>();
			map.put("SEARCH", Byte.valueOf("0"));
			map.put("CAT", Byte.valueOf("1"));
			map.put("NOSEARCH", Byte.valueOf("2"));
			map.put("SUMMARY", Byte.valueOf("3"));
			
			for(int i = 0; i < size; i++){
				JSONObject item = jsonList.getJSONObject(i);
				
				if(item.getDate("date").getTime() == lastDay.getTime()){//前一天的数据会出现这种情况
					lastDayRecordTotal++;
					if(!(item.containsKey("indirectpay") || item.containsKey("favitemcount") || item.containsKey("indirectpaycount") ||
							item.containsKey("directcarttotal") || item.containsKey("indirectcarttotal") || item.containsKey("carttotal") ||
							item.containsKey("favshopcount") || item.containsKey("directpay") || item.containsKey("directpaycount"))){
						//这些都没有，认为没有数据，
						lastDayNoDataNum++;
						continue;
					}
				}
				
				int indirectpay = NumberUtils.toInt(item.getString("indirectpay"), 0);
				int	favItemCount = NumberUtils.toInt(item.getString("favitemcount"), 0);
				int	indirectpaycount = NumberUtils.toInt(item.getString("indirectpaycount"), 0);
				int	favShopCount = NumberUtils.toInt(item.getString("favshopcount"), 0);
				int	directpay = NumberUtils.toInt(item.getString("directpay"), 0);
				int	directpaycount = NumberUtils.toInt(item.getString("directpaycount"), 0);
				int directcarttotal = NumberUtils.toInt(item.getString("directcarttotal"), 0);
				int indirectcarttotal = NumberUtils.toInt(item.getString("indirectcarttotal"), 0);
				int carttotal = NumberUtils.toInt(item.getString("carttotal"), 0);
				
				//根据key找到相关的
				for(RptKeyword rpt : list){
					
					if(rpt.getAdgroupId().equals(item.getLong("adgroupid")) &&
							rpt.getKeywordId().equals(item.getLong("keywordid")) &&
							rpt.getSource().equals(item.getByte("source")) &&
							rpt.getSearchType().equals(map.get(item.getString("searchtype"))) && 
							rpt.getDate().getTime() == item.getDate("date").getTime()){
						
						rpt.setDirectPay(directpay) ;
						rpt.setIndirectPay(indirectpay); 
						rpt.setDirectPayCount(directpaycount);
						rpt.setIndirectPayCount(indirectpaycount);
						rpt.setFavShopCount(favShopCount) ;
						rpt.setFavItemCount(favItemCount); 	
						rpt.setCartTotal(carttotal);
						rpt.setDirectCartTotal(directcarttotal);
						rpt.setIndirectCartTotal(indirectcarttotal);
						
						break;
					}
				}		
			}
		}else{
			logger.warn("can not get any info from proxy, maybe something is wrong, api is combineRptKeywordEffect, response: {}", response);
			throw new ApiException();
		}
		lastDayRecord.put("total", lastDayRecordTotal);
		lastDayRecord.put("lost", lastDayNoDataNum);
		
		return size;
	}
	
	public int insertRptKeywordScore(String userId, List<Score> scoreList){
		
		List<RptKeyword> list = new ArrayList<RptKeyword>();
		
		Date dateNow = new Date();
		dateNow = Util.getYYYYMMDD(dateNow);
		
		for(Score score : scoreList){
			
			RptKeyword rpt = new RptKeyword();
			rpt.setTaobaoUserId(Long.valueOf(userId));
			rpt.setUser_id(userId);
			rpt.setCpc(0f);
			rpt.setCtr(0f);
			rpt.setImpressions(0) ;
			rpt.setCpm(0f);
			rpt.setClick(0);
			rpt.setCost(0) ;
			rpt.setAdgroupId(score.getAdgroupId());
			rpt.setCampaignId(score.getCampaignId());
			rpt.setDate(dateNow);
			rpt.setSearchType(Byte.valueOf("27"));
			rpt.setSource(Byte.valueOf("23"));
			rpt.setAvgpos(0f);
			rpt.setKeywordId(score.getKeywordId());
			String word = score.getWord();
			if(word == null || score.getAdgroupId() == 0 ){
				logger.warn("insertRptKeywordScore userId {}, keyword id {}, word is {}, adgroupId {}", userId, score.getKeywordId(), word, score.getAdgroupId());
				Keywords keyword = mapper.selectByPrimaryKey(userId, score.getKeywordId());
				word = keyword.getWord();
				rpt.setAdgroupId(keyword.getAdgroupId());
				rpt.setCampaignId(keyword.getCampaignId());
			}
			
			rpt.setKeywordstr(word);
			rpt.setDirectPay(0);
			rpt.setIndirectPay(0); 
			rpt.setDirectPayCount(0);
			rpt.setIndirectPayCount(0);
			rpt.setFavShopCount(0);
			rpt.setFavItemCount(0); 	
			rpt.setCartTotal(0);
			rpt.setDirectCartTotal(0);
			rpt.setIndirectCartTotal(0);
			int qscore = NumberUtils.toInt(score.getQscore(), 0);
			rpt.setQscore(qscore);
			int wirelessQscore = NumberUtils.toInt(score.getWirelessQscore(), 0);
			rpt.setWirelessQscore(wirelessQscore);
			
			list.add(rpt);
		}
		
		return insertRptKeywordsBatch(userId, list);
	}
	
	@Override
	public void updateRptKeywordData(String userId, List<RptKeyword> list){
		
		for(RptKeyword rpt : list){
			rpt.setTaobaoUserId(Long.valueOf(userId));
			rpt.setUser_id(userId);
		}
	}
	
	@Override
	public boolean getRemoteFile(String strUrl, String fileName) throws IOException { 
		
		URL url = new URL(strUrl); 
		HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
		DataInputStream input = new DataInputStream(conn.getInputStream()); 
		DataOutputStream output = new DataOutputStream(new FileOutputStream(fileName)); 
		byte[] buffer = new byte[1024 * 8]; 
		int count = 0; 
		
		while ((count = input.read(buffer)) > 0) { 
			output.write(buffer, 0, count); 
		} 
		output.close(); 
		input.close(); 
		return true; 
	}

	@Override
	public boolean existKeywordsTable(String userId) {
		// TODO Auto-generated method stub
		String tableName = "keywords"+userId;
	
		return mapper.existKeywordsTable(tableName) > 0;
	}

	@Override
	public int createKeywordsTable(String userId) {
		// TODO Auto-generated method stub
		return mapper.createKeywordsTable(userId);
	}
	
	@Override
	public int alterKeywordsTable(String userId){
		
		return mapper.alterKeywordsTable(userId);
	}

	@Override
	public boolean existRptKeywordsTable(String userId) {
		// TODO Auto-generated method stub
		String tableName = "rpt_keyword"+userId;
		
		return rptmapper.existRptKeywordsTable(tableName) > 0;
	}

	@Override
	public int createRptKeywordsTable(String userId) {
		// TODO Auto-generated method stub
		return rptmapper.createRptKeywordsTable(userId);
	}
	
	@Override
	public int alterRptKeywordsTable(String userId){
		
		return rptmapper.alterRptKeywordsTable(userId);
	}
	
	@Override
	public Date getLastDateByWord(String keywordStr){
		
		return insightKeywordMapper.selectLastDateByWord(keywordStr);
	}
	
	public List<InsightKeywordData> getAndParseLInsightKeywordData(long userId, String date, List<String> words){
		
		List<InsightKeywordData> data = new ArrayList<InsightKeywordData>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		Date dateFormat = new Date();
		try {
			dateFormat = sdf.parse(date);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//注意要分页
		if(words != null && words.size() > 0){
			int pageSize = 70;
			int fromIndex = 0;
			int endIndex = 0;
			
			do{
				endIndex += pageSize; 
				if(endIndex > words.size()){
					endIndex = words.size();
				}
				
				StringBuilder sb = new StringBuilder();
				int index = fromIndex;
				for(; index < endIndex-1; index++){
					sb.append(words.get(index));
					sb.append(",");
				}
				sb.append(words.get(index));
				InsightKeywordDataResponse response = null;
				try{
					response = proxy.getInsightKeywordData(userId, sb.toString(), date, date);
				}catch(Exception e){
					e.printStackTrace();
					logger.warn("getAndParseLInsightKeywordData something is wrong, userId {}, date {}", userId, date);
				}
				
				if(response != null && response.getRes() != null && response.getRes().getResult() != null){
					List<InsightWord> dto = response.getRes().getResult().getDto(); 
					if(dto != null && dto.size() > 0){
						parseInsightData(dateFormat, dto, data);
					}
				}
				
				fromIndex += pageSize; 
				
			}while(fromIndex < words.size());	
		}
		
		return data;
	}
	
	public List<WordInsightMetric> getInsightWordData(Long userId, String startDate, String endDate, List<String> words){
		
		List<WordInsightMetric> data = new ArrayList<WordInsightMetric>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		Date startDateFormat = new Date();
		Date endDateFormat = new Date();
		try {
			startDateFormat = sdf.parse(startDate);
			endDateFormat = sdf.parse(endDate);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if(words != null && words.size() > 0){
	
			int fromIndex = 0;
			Scope scope = new Scope(startDateFormat, endDateFormat);
			
			do{
				StringBuilder sb = new StringBuilder();
				
				while(fromIndex < words.size()){
					
					sb.append(words.get(fromIndex));
					if(sb.length() >= Util.MaxUriLength){
						fromIndex++;
						logger.warn(">>>>>> getInsightWordData userId: {} split", userId);
						break;
					}else{
						sb.append(",");
						fromIndex++;
					}
				}
				
				InsightWordDataResponse response = null;

				try{
					response = proxy.getInsightWordData(userId, sb.toString(), startDate, endDate);
					
				}catch(Exception e){
					e.printStackTrace();
					logger.warn("getInsightWordData something is wrong, userId: {}, word len: {}", userId, sb.length());
				}
				
				if(response != null && response.getRes() != null && response.getRes().getResult() != null){
					List<InsightWordData> dto = response.getRes().getResult().getDto(); 
					if(dto != null && dto.size() > 0){
						for(InsightWordData item : dto){
							WordInsightMetric keywordMetric = new WordInsightMetric();
							keywordMetric.from(item, scope);
							String wordStr = item.getBidword();
							KeywordStrTemp temp = wordTempRep.findOne(wordStr);
							if(temp != null){
								keywordMetric.setKeywordIDs(temp.getKeywordIDs());
								keywordMetric.setAdgroupIDs(temp.getAdgroupIDs());
							}else{
								logger.warn("getInsightWordData something is wrong, userId: {}, word: {}", userId, wordStr);
							}
							
							keywordMetric.setupMetricID();
							data.add(keywordMetric);
						}
					}
				}
				
			}while(fromIndex < words.size());	
		}
		
		return data;
		
	}
	
	public int insertInsightKeywordDataBatch(List<InsightKeywordData> list){
		
		int num = 0;
		
		if(list != null && list.size() > 0){
			num = insightKeywordMapper.insertBatch(list);
		}
		
		return num;
	}
	
	private void parseInsightData(Date date, List<InsightWord> dto, List<InsightKeywordData> insightData){
		
		for(InsightWord item : dto){
			
			InsightKeywordData data = new InsightKeywordData();
			
			data.setClick(item.getClick());
			data.setCompetition(item.getCompetition());
			data.setCost(item.getCost());
			data.setCoverage(NumberUtils.toFloat(item.getCoverage(), 0.0f));
			data.setCpc(NumberUtils.toFloat(item.getCpc(), 0.0f));
			data.setCtr(NumberUtils.toFloat(item.getCtr(), 0.0f));
			data.setDate(date);
			data.setDirecTtransaction(item.getDirectTransaction());
			data.setDirectTransactionShipping(item.getDirectTransactionShipping());
			data.setFavItemTotal(item.getFavItemTotal());
			data.setFavShopTotal(item.getFavShopTotal());
			data.setFavTotal(item.getFavTotal());
			data.setImpression(item.getImpression());
			data.setIndirectTransaction(item.getIndirectTransaction());
			data.setIndirectTransactionShipping(item.getIndirectTransactionShipping());
			data.setKeywordstr(item.getBidword());
			data.setRoi(NumberUtils.toFloat(item.getRoi(), 0.0f));
			data.setTransactionShippingTotal(item.getTransactionShippingTotal());
			data.setTransactionTotal(item.getTransactionTotal());
			
			insightData.add(data);
		}
	}
	
	@Override
	public boolean saveInsightWordData(List<WordInsightMetric> list){
		
		keywordRep.save(list);
		
		return true;
	}
	
	@Override
	public boolean deleteByScopeEndTime(Date endTime){
		
		keywordRep.deleteByScopeEndTime(endTime);
		
		return true;
	}
	
	@Override
	public boolean existsByWordAndScopeEndTime(String word, Date endTime){
		
		int count = keywordRep.countByWordAndScopeEndTime(word, endTime);
		
		return count > 0;
	}
	
	@Override
	public boolean existsKeywordStrTempByWord(String word){
		
		return wordTempRep.exists(word);
	}
	
	@Override
	public KeywordStrTemp getKeywordStrTempByWord(String word){
	
		return wordTempRep.findOne(word);
	}
	
	@Override
	public boolean saveKeywordStrTempList(List<KeywordStrTemp> list){
		
		wordTempRep.save(list);
		
		return true;
	}
}